home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Games / Abalone 1.4.2 / src / SoundPlay.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-21  |  4.2 KB  |  194 lines  |  [TEXT/MPS ]

  1. #define SOUNDPLAY_C
  2. #include "SoundPlay.h"
  3. #undef SOUNDPLAY_C
  4.  
  5.  
  6. #pragma segment More
  7.  
  8.  
  9. static Boolean            gSoundAsync = true;
  10. static SndChannelPtr    gChannel = nil;
  11.  
  12.  
  13. void
  14. SndPlayMove (BoardPtr board, FieldsPtr move, short direction)
  15. {
  16.     short balls = 0;
  17.     Field cur;
  18.     
  19. //    Count the number of balls moved.
  20.     
  21.     for (cur = move[0]; cur != 0 && board->field[cur] != empty; cur = Neighbour (cur, direction))
  22.         balls++;
  23.     
  24. //    Play the right resource for the number of balls moved:
  25. //    The sound resources are ordered; 10001 = 1 ball, 10002 = 2 balls etc.
  26.     
  27.     PlayResource (& gChannel, 10000 + balls);
  28. }
  29.  
  30.  
  31.  
  32. void
  33. SndPlayFlicheMove (BoardPtr board, FieldsPtr move, short direction)
  34. {
  35. #if ! defined(__SC__) && ! defined (__MWERKS__)
  36. #pragma unused (board, direction)
  37. #endif
  38.  
  39. //    Play the right resource for the number of balls moved:
  40. //    The sound resources are ordered; 20001 = fliche of 2, 20003 = fliche of 3. */
  41.  
  42.     PlayResource (& gChannel, move[2] ? 20003 : 20002);
  43. }
  44.  
  45.  
  46.  
  47. void
  48. SndPlayBallDown (void)
  49. {
  50. //    Play the resource for a downed ball.
  51.     
  52.     PlayResource (& gChannel, 10000);
  53. }
  54.  
  55.  
  56.  
  57. void
  58. SndPlayBeep (void)
  59. {
  60.     SndDisposeChannels();
  61.     SysBeep (1);
  62. }
  63.  
  64.  
  65.  
  66. SndChannelPtr
  67. CreateSoundChannel (void)
  68. {    
  69. #    define TURNOFF { Warning (SOUND_TURNED_OFF); DisposeSoundChannel (& channel); gSet.SoundOn = false; return nil; }
  70.     SndChannelPtr channel = nil;
  71.         
  72. //    Problem: to play async, a channel must be allocated and passed to SndPlay.
  73. //    On a Plus, SndPlay seems unwilling to play compressed sounds async,
  74. //    and even to play them at all, if a non-nil channel is passed to it.
  75. //    The unelegant solution I found for this works as follows:
  76. //    First, I create a sound channel, pass it to SndPlay,
  77. //    and if the result tells me not enough hardware is present,
  78. //    I dispose the channel and (automatically, since channel is nil) switch to synchronous play
  79. //    gSoundAsync tells me if it is still worth trying to play async.
  80.  
  81.     if (gSoundAsync)
  82.     {
  83.     //    Try to open a sampled sound synthesizer with MACE3 decompression
  84.  
  85.         OSErr error;    
  86.         short initParam = initMACE3 + initMono + initNoInterp;
  87.         SndCommand testCmd = { availableCmd, 0, initMACE3 };
  88.  
  89.         if ((error = SndControl (sampledSynth, & testCmd)) != noErr)
  90.             TURNOFF;
  91.             
  92.         if (testCmd.param2 == 0)
  93.             initParam -= initMACE3;
  94.                 
  95.         if ((error = SndNewChannel (& channel, sampledSynth, initParam, nil)) != noErr || channel == nil)
  96.             TURNOFF;
  97.     }
  98.     return channel;
  99. }
  100.  
  101.  
  102.  
  103. void
  104. SndDisposeChannels (void)
  105. {
  106.     DisposeSoundChannel (& gChannel);
  107. }
  108.  
  109.  
  110.  
  111. void
  112. DisposeSoundChannel (SndChannelPtr *channel)
  113. {
  114.     if (*channel == nil)
  115.         return;
  116.         
  117.     (void) SndDisposeChannel (*channel, false);
  118.     *channel = nil;    
  119. }
  120.  
  121.  
  122.  
  123. Boolean
  124. PlayResource (SndChannelPtr *channel, short resID)
  125. {
  126.     Handle sound;
  127.     OSErr error;
  128.     
  129. //    Set up the sound channel
  130.     
  131.     if (gSoundAsync && gChannel != nil)
  132.     {
  133.         SCStatus status;
  134.         OSErr error;
  135.         
  136.         error = SndChannelStatus (gChannel, sizeof (SCStatus), & status);
  137.         if (status.scChannelBusy)
  138.             DisposeSoundChannel (& gChannel);
  139.     }
  140.     if (gSoundAsync && gChannel == nil)
  141.         gChannel = CreateSoundChannel();
  142.         
  143. //    Get the requested sound resource
  144.     
  145.     if ((sound = GetResource ('snd ', resID)) == nil)
  146.     {
  147.         Warning (SND_RESOURCE_MISSING);
  148.         DisposeSoundChannel (channel);
  149.         gSet.SoundOn = false;
  150.         return false; 
  151.     }
  152.     
  153. //    Try to play the sound; if (still) gSoundAsync, try asynchronous.
  154.         
  155.     MoveHHi (sound);
  156.     HNoPurge (sound);
  157.     HLock (sound);
  158.     
  159. #if defined(THINK_C)    
  160.     error = SndPlay (*channel, sound, gSoundAsync);
  161. #else
  162.     error = SndPlay (*channel, (SndListHandle) sound, gSoundAsync);
  163. #endif
  164.     
  165.     HUnlock (sound);
  166.     HPurge (sound);
  167.  
  168.     if (error != noErr)
  169.     {
  170.     //    if an error occurred, see if this is a result of trying to play asynchronous
  171.     //    on a Mac that does not seem to support this */
  172.          
  173.         if (gSoundAsync && (error == -200 || error == -201))    //    yep, not enough hardware error
  174.         {
  175.         //    Switch to synchronous; dispose of the channel.
  176.         //    Don't bother telling the user:
  177.         //    he/she has no choise in the matter.
  178.             
  179.             DisposeSoundChannel (channel);
  180.             gSoundAsync = false;
  181.             return PlayResource (channel, resID);    //    recursive call, with gSoundAsync changed
  182.         }
  183.         else
  184.         {
  185.         //    worse yet than 'not enough hardware, so turn sound off completely.
  186.             
  187.             Warning (SOUND_TURNED_OFF);
  188.             DisposeSoundChannel (channel);
  189.             gSet.SoundOn = false;
  190.             return false; 
  191.         }
  192.     }
  193.     return true;
  194. }